package io.kiki.stack.netty.processor;

import io.kiki.stack.netty.channelManager.ChannelContext;
import io.kiki.stack.netty.command.AbstractRequestCommand;
import io.kiki.stack.netty.command.ResponseType;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicBoolean;


@Slf4j
@Setter
@Getter
public class AsyncContextImpl implements AsyncContext {

    private final ChannelContext channelContext;


    private final AbstractRequestCommand requestCommand;

    private final RequestProcessor processor;

    private final AtomicBoolean isResponseSentAlready = new AtomicBoolean();


    public AsyncContextImpl(final ChannelContext channelContext, final AbstractRequestCommand requestCommand, final RequestProcessor processor) {
        this.channelContext = channelContext;
        this.requestCommand = requestCommand;
        this.processor = processor;
    }


    @Override
    public void sendResponse(Object responseObject) {
        if (isResponseSentAlready.compareAndSet(false, true)) {
            processor.sendResponseIfNecessary(this.channelContext, requestCommand.getType(), processor.getCommandFactory().createResponse(responseObject, this.requestCommand));
        } else {
            throw new IllegalStateException("Should not send rpc response repeatedly!");
        }
    }


    @Override
    public void sendException(Throwable ex) {
        if (isResponseSentAlready.compareAndSet(false, true)) {
            processor.sendResponseIfNecessary(this.channelContext, requestCommand.getType(), processor.getCommandFactory().createExceptionResponse(this.requestCommand.getId(), ResponseType.server_exception, ex));
        } else {
            throw new IllegalStateException("Should not send rpc response repeatedly!");
        }
    }
}